/*-------------------------------------------------*  
 下拉树:
 使用方法:(comobox可用的参数一般都可用)
 {
 xtype : 'combotree',
 id:'com',
 fieldLabel : '试题分类',
 hiddenName : 'tkId',------------
 sm : 'leaf',--------------仅叶子可选
 defaultId : '2',-------------默认ID
 defaultText : '测试分类',----------默认text( 显示值 ),
 anchor : "90%",
 dataUrl : '../../tiku.do?action=getTikuTree'-----------------tree的dataUrl
 }
 使用setDefaultValue设置默认值,其他跟comobo一样
 }
 *-----------------------------------------------------*/
Bee.ComboBoxTree = Ext.extend(Ext.form.ComboBox, {
    rootText: '根节点',
    rootId: '-1',
    rootVisible: true,
    checked: undefined,
    /**
     * ------------------------------------- 该combotree的ID
     * -------------------------------------
     */
    id: null,
    name: null,
    /**
     * ------------------------------------- 作为隐藏域的name属性
     * -------------------------------------
     */
    hiddenName: null,
    /**
     * ------------------------------------- 下拉树的 所有可选 all 叶子可选 leaf
     * 文件夹可选 folder
     *
     * @default false -------------------------------------
     */
    sm: 'all',
    /**
     * 是否可缩放
     *
     * @type Boolean
     */
    resizable: true,
    /**
     * ----------------------- 树显示的高度，默认为200 -----------------------
     */
    treeHeight: 200,
    /**
     * 默认的ID和text
     *
     * @type
     */
    defaultId: null,
    defaultText: null,
    /**
     * 空的store
     */
    store: new Ext.data.SimpleStore({
        fields: [],
        data: [[]]
    }),
    editable: false, // 禁止手写及联想功能
    mode: 'local',
    triggerAction: 'all',
    selectedClass: '',
    onSelect: Ext.emptyFn,
    lazyInit: false,
    /**
     * -------------------------------------- 下拉树被点击事件添加一处理方法
     *
     * @param node
     *            --------------------------------------
     */
    onTreeSelected: function(node){
        this.onSelect(this, node);
    },
    /**
     * 放弃这些方法:因为父类这些方法是通过读取store 取值,显然跟现在的tree中取值不一样
     *
     * @param {}
     *            v
     */
    setDefaultValue: function(text, id){
        if (id) {
            this.value = id;
            Bee.ComboBoxTree.superclass.setValue.call(this, id);
        }
        if (text) {
            Bee.ComboBoxTree.superclass.setRawValue.call(this, text);
        }
    },
    /**
     * 一定得覆盖此方法,置空,因为这个依赖的是tree而不是store
     */
    setValue: function(val){
        if (this.tree && this.tree.root) {
            this.tree.getSelectionModel().clearSelections(true);
            Ext.each(this.tree.getChecked(), function(node){
                node.getUI().toggleCheck(false);
            });
            if (Ext.isArray(val)) {
                var ids = [], texts = [];
                
                Ext.each(val, function(item){
                    ids.push(item.id);
                    texts.push(item.text);
                    this.tree.root.cascade(function(node){
                        if (item.id == node.id) {
                            node.getUI().toggleCheck(true);
                            this.tree.getSelectionModel().select(node, true);
                        }
                    }, this);
                }, this);
                
                this.value = ids.join(',');
                Bee.ComboBoxTree.superclass.setRawValue.call(this, texts.join(','));
            }
            else {
                var node = this.tree.root.findChild('id', val);
                if (node) {
                    this.tree.getSelectionModel().select(node);
                    this.value = val;
                    Bee.ComboBoxTree.superclass.setRawValue.call(this, node.attributes[this.displayField]);
                }
            }
            if (this.hiddenField) {
                this.hiddenField.value = Ext.value(this.value, '');
            }
        }
    },
    /**
     * 取hiddenName的值,必须覆盖此方法
     */
    getValue: function(){
        return Ext.isDefined(this.value) ? this.value : '';
    },
    /**
     * 取显示text的值
     */
    /*
     * getRawValue:function(){ },
     */
    /**
     * ---------------------------------- 树的单击事件处理
     *
     * @param node,event
     *            ----------------------------------
     */
    treeClk: function(node, e){
        if (node.isLeaf()) {
            if (this.sm != 'leaf') {
                e.stopEvent();
                return;
            }
        }
        else {
            if (this.sm == 'leaf') {
                e.stopEvent();
                return;
            }
        }
        this.tree.getSelectionModel().select(node);
        this.collapse();// 隐藏option列表
        // 选中树节点后的触发事件
        this.fireEvent('treeselected', node);
    },
    onViewClick: function(){
    },
    /**
     * 初始化 Init
     */
    initComponent: function(){
        Bee.ComboBoxTree.superclass.initComponent.call(this);
        // tree
        var comobo = this;
        var tree = new Ext.tree.TreePanel({
            selectedNodes: [],
            rootVisible: this.rootVisible,
            autoScroll: true,
            border: false,
            selModel: this.checked ? new Ext.tree.MultiSelectionModel() : new Ext.tree.DefaultSelectionModel(),
            loader: new Bee.tree.DWRTreeLoader({
                dwrCall: this.dwrCall,
                preloadChildren: true,
                listeners: this.loaderListeners,
                nodeMeta: {
                    id: this.valueField,
                    text: this.displayField,
                    leaf: this.leaf,
                    isChecked: this.checked
                },
                listeners: {
                    'load': function(){
                        if (this.value) {
                            if (this.value.indexOf && this.value.indexOf(',') > -1) {
                                Ext.each(this.value.split(','), function(id){
                                    this.tree.root.cascade(function(node){
                                        if (id == node.id) {
                                            node.getUI().toggleCheck(true);
                                            this.tree.getSelectionModel().select(node, true);
                                        }
                                    }, this);
                                }, this);
                            }
                            else {
                                var node = this.tree.root.findChild('id', this.value, true);
                                if (node) {
                                    node.getUI().toggleCheck(true);
                                    this.tree.getSelectionModel().select(node, true);
                                }
                            }
                        }
                    },
                    scope: comobo
                }
            }),
            root: new Ext.tree.AsyncTreeNode({
                expandable: true,
                expanded: true,
                text: this.rootText,
                id: this.rootId
            })
            /**,
             tbar: [{
             text: '展开',
             handler: function() {
             tree.expandAll();
             }
             }, {
             text: '折叠',
             handler: function() {
             tree.collapseAll();
             }
             }, '-', {
             text: '清除所选',
             handler: function() {
             comobo.clearValue();
             }
             }]
             */
        });
        this.tree = tree;
        this.tree.height = this.treeHeight;
        this.tree.containerScroll = false;
        this.tplId = Ext.id();
        this.tpl = '<div id="' + this.tplId + '" style="height:' + this.treeHeight + ';overflow:hidden;"></div>';
        /**
         * ----------------------- 添加treeselected事件， 选中树节点会激发这个事 件，
         * 参数为树的节点 ------------------------
         */
        this.addEvents('treeselected');
        this.on('treeselected', this.onTreeSelected, this);
    },
    /**
     * ------------------ 事件监听器 Listener ------------------
     */
    listeners: {
        'expand': {
            fn: function(){
                if (!this.tree.rendered && this.tplId) {
                    this.tree.render(this.tplId);
                }
                this.tree.show();
            },
            single: true
        },
        'render': {
            fn: function(){
                this.tree.on('click', this.treeClk, this);
                this.on('collapse', this.onCollapse, this);
                // 初始化空值显示
                Bee.ComboBoxTree.superclass.setRawValue.call(this, this.emptyText);
                // 初始化 默认数值
                this.setDefaultValue(this.defaultText, this.defaultId);
            },
            single: true
        },
        'beforedestroy': {
            fn: function(cmp){
                this.purgeListeners();
                this.tree.purgeListeners();
            }
        }
    },
    onCollapse: function(){
        var text = '';
        if (this.hiddenName) {
            if (this.checked) {
                var nodes = this.tree.getChecked(), ids = [], texts = [];
                Ext.each(nodes, function(selNode){
                    ids.push(selNode.id);
                    texts.push(selNode.text);
                });
                
                this.value = ids.join(',');
                Bee.ComboBoxTree.superclass.setValue.call(this, ids.join(','));
                text = texts.join(',');
            }
            else {
                var node = this.tree.getSelectionModel().getSelectedNode();
                if (node) {
                    this.value = node.id;
                    Bee.ComboBoxTree.superclass.setValue.call(this, node.id);
                    text = node.text;
                }
            }
        }
        Bee.ComboBoxTree.superclass.setRawValue.call(this, text);
    },
    expand: function(){
        if (this.isExpanded()) {
            return;
        }
        if (this.title || this.pageSize) {
            this.assetHeight = 0;
            if (this.title) {
                this.assetHeight += this.header.getHeight();
            }
            if (this.pageSize) {
                this.assetHeight += this.footer.getHeight();
            }
        }
        if (this.bufferSize) {
            this.doResize(this.bufferSize);
            delete this.bufferSize;
        }
        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
        // zindex can change, re-check it and set it if necessary
        var listParent = Ext.getDom(this.getListParent() || Ext.getBody()), zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
        if (!zindex) {
            zindex = this.getParentZIndex();
        }
        if (zindex) {
            this.list.setZIndex(zindex + 5);
        }
        this.list.show();
        if (this.value) {
            this.value = this.value + '';
            if (this.value.indexOf(',') > -1) {
                Ext.each(this.value.split(','), function(id){
                    this.tree.root.cascade(function(node){
                        if (id == node.id) {
                            node.getUI().toggleCheck(true);
                            this.tree.getSelectionModel().select(node, true);
                        }
                    }, this);
                }, this);
            }
            else {
                var node = this.tree.root.findChild('id', this.value, true);
                if (node) {
                    node.getUI().toggleCheck(true);
                    this.tree.getSelectionModel().select(node, true);
                }
            }
        }
        if (Ext.isGecko2) {
            this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
        }
        this.mon(Ext.getDoc(), {
            scope: this,
            mousewheel: this.collapseIf,
            mousedown: this.collapseIf
        });
        this.fireEvent('expand', this);
    }
});

/**
 * --------------------------------- 将Bee.ComboBoxTree注册为Ext的组件,以便使用
 * Ext的延迟渲染机制，xtype:'combotree' ---------------------------------
 */
Ext.reg('combotree', Bee.ComboBoxTree);
